use {
    tron,
    commons::error,
    repository::model::{
        dapp_centralized_config::DAppCentralizedConfig,
        dapp_transaction::{DAppTransaction, DAppTransactionVO, TransactionStatus},
    },
    sqlx::{MySql, Pool},
    tracing::{error, debug, info},
};

#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
struct CollectRequest {
    pub contract: String,
    pub from_addr: String,
    pub to_addr: String,
    pub hash: String,
    pub time_stamp: String,
    pub num: String,
    pub decimals: u8,
}

impl CollectRequest {
    fn from(transaction: DAppTransactionVO, collect_addr: &str, collect_hash: &str) -> Self {
        CollectRequest {
            contract: transaction.contract,
            from_addr: transaction.recharge_addr,
            to_addr: collect_addr.to_string(),
            hash: collect_hash.to_string(),
            time_stamp: transaction.time_stamp,
            num: transaction.num,
            decimals: transaction.decimals,
        }
    }

    fn collect_url() -> &'static str {
        "http://127.0.0.1:8080/collect"
    }
}

pub async fn collect_job(
    env: &str,
    chain: &str,
    pool: &Pool<MySql>,
    config: &DAppCentralizedConfig,
    transaction: &DAppTransactionVO,
) -> anyhow::Result<()> {
    let id = transaction.id.unwrap();
    debug!("collect job [{id}] has ready.");
    DAppTransaction::update_status(
        pool,
        id,
        u8::from(TransactionStatus::CollectProcessing),
    )
    .await;
    let payer_key_str = config.payer_pr.clone();
    let to_addr = config.collect_addr.clone();

    let recharge_hash = transaction.recharge_hash.clone();

    let contract_key_opt = transaction.contract_key.clone();
    let contract = transaction.contract.clone();
    let from_addr = transaction.recharge_addr.clone();
    let from_key = transaction.from_key.clone();
    let num_str = transaction.num.clone();
    let num = num_str.parse::<u64>()?;

    let collect_hash = match chain {
        "TRON" => {
            let client = tron::base::client::build_client(env);

            tron::biz::collect::token_collect(
                &client,
                contract.as_str(),
                from_key.as_str(),
                payer_key_str.as_str(),
                to_addr.as_str(),
                num_str.as_str(),
            )
            .await?
        },
        _ => String::new(),
    };

    /*
    let request = CollectRequest::from((*transaction).clone(), &to_addr, &collect_hash);
    let client = reqwest::Client::new();
    let resp= client
        .post(CollectRequest::collect_url())
        .json(&request)
        .send()
        .await?;

    if resp.status().is_success() {
    */
    if true {
        info!("collect recharge [{recharge_hash}] success: {collect_hash}");
        DAppTransaction::update_collect_info(
            pool,
            transaction.id.unwrap(),
            u8::from(TransactionStatus::Success),
            &to_addr,
            &collect_hash,
        )
        .await;
    } else {
        // error!("collect recharge [{recharge_hash}] request error: {}", resp.status().as_str());
        error!("collect recharge [{recharge_hash}] request error");
        DAppTransaction::update_status(
            pool,
            transaction.id.unwrap(),
            u8::from(TransactionStatus::RechargeSuccess),
        )
        .await;
    }

    Ok(())
}
